package com.zwh.tool.utils;


import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 反射辅助工具类
 */
public class ReflectUtils {


    public static Object methodReflect(Class<?> aClass, String methodName) {
        return methodReflect(aClass, methodName, null, null);
    }

    public static Object methodReflect(Class<?> aClass, String methodName, Object... source) {
        return methodReflect(aClass, methodName, null, source);
    }

    /**
     * @param aClass     要反射的实体类
     * @param methodName 要反射的方法名
     * @param nullClass  有些传参是传空参,此时有些底层要接收Class对象,null没法判断是什么Class对象,因此那部分空的就放这里
     * @param values     要反射的方法的传参
     * @return
     */
    public static Object methodReflect(Class<?> aClass, String methodName, Class<?>[] nullClass, Object... values) {
        Object result = null;
        int num = 0;//第几个空Class对象
        Method method;
        try {
            if (values == null) {
                method = aClass.getDeclaredMethod(methodName);
            } else {
                Class<?>[] argsClass = new Class<?>[values.length];
                for (int i = 0; i < values.length; i++) {
                    if (values[i] == null) {
                        argsClass[i] = nullClass[num];
                        num = num + 1;
                    } else {
                        argsClass[i] = values[i].getClass();
                    }
                }
                method = aClass.getDeclaredMethod(methodName, argsClass);
            }
            method.setAccessible(true);
            if (Modifier.isStatic(method.getModifiers())) {
                result = method.invoke(null, values);
            } else {
                Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
                declaredConstructor.setAccessible(true);
                Object instance2 = declaredConstructor.newInstance();
                result = method.invoke(instance2, values);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
